#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
require 'rexml/document'
#include libxml 
include REXML

# nexparse.rb
# alex_annese[at]rapid7[dot]com
#
# Parse a NeXpose XML report in various ways
#
# usage:
# ./nexport.rb [-psiIHh] ... [FILE]

options = OpenStruct.new

opts = OptionParser.new do |opt|

    opt.separator ''
    opt.separator ' nexparse.rb'
    opt.separator ' NeXpose XML Parser'
    opt.separator ' ------------------'

    opt.banner = "Usage: nexport.rb [-psiHh] ... FILE"

    opt.separator ''
    opt.separator 'List options:'

    # --listip
    opt.on('-i', '--listip', 'List all IP addresses.') do |listip|
        options.listip = listip
    end

    # --listhost
    opt.on('-H', '--listhost', 'List all hostnames.') do |listhost|
        options.listhost = listhost
    end

    opt.separator ''
    opt.separator 'Search options:'

    # --port PORT_NUMBER
    opt.on('-p', '--port NUM', 'List IPs based on port.') do |port|
        options.port = port
    end

    # --service SERVICE_NAME
    opt.on('-s', '--service STRING', 'List IPs based on service.') do |service|
        options.service = service
    end

    # --porthost PORT_NUMBER
    opt.on('-P', '--porthost NUM', 'List hostnames based on port.') do |porthost|
        options.porthost = porthost
    end

    # --servicehost SERVICE_NAME
    opt.on('-S', '--servicehost STRING', 'List hostnames based on service.') do |servicehost|
        options.servicehost = servicehost
    end

    opt.separator ''
    opt.separator 'Common options:'

    # no argument
    opt.on_tail('-h', '--help', 'Show this message.') do
        puts opts
        exit
    end
end

if ARGV.empty?
    puts opts
    exit
end

opts.parse!(ARGV)
options.file = ARGV.last

root = Document.new File.new(ARGV.last)

#libxml code
#xp = XML::Parser.new()
#xp.string = ARGV.last
#root = xp.parse

node = "/NexposeReport/nodes/node[endpoints/endpoint"
nod3 = "/NexposeReport/nodes/node/names/name"

# --listip
if listip = options.listip
    #    root.find('/NexposeReport/nodes/node/').each do |elem|
    #        elem.find("address")[0].child.to_s
    #        uri = URI.parse( link )
    #        puts uri
    #    end 

    root.elements.each("/NexposeReport/nodes/node/") do |elem|
        puts elem.attributes["address"]
    end

    # --listhost
elsif listhost = options.listhost
    XPath.each(root, "//name") { |element| puts element.text }

    # --porthost PORT_NUMBER
    # currently broken
elsif porthost = options.porthost
    XPath.each(root, "//name") { |e| foo(e) }
    root.elements.each("#{node}[@port = %s]]" % porthost) do |elem|
        puts "found something..."
    end

    # --servicehost SERVICE_NAME
    # currently broken
elsif servicehost = options.servicehost
    root.elements.each("#{node}/services/service[@name = '%s']]" % servicehost.upcase) do |elem|
        puts "found something..."
    end

    # --port PORT_NUMBER
elsif port = options.port 
    root.elements.each("#{node}[@port = %s]]" % port) do |elem|
        puts elem.attributes["address"]
    end

    # --service SERVICE_NAME
elsif service = options.service
    root.elements.each("#{node}/services/service[@name = '%s']]" % service.upcase) do |elem|
        puts elem.attributes["address"]
    end
end

# :wq!
